package source;

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
/**
 *
 * @author Sabitov Artem
 */
public class mpMain extends Thread {
	private static mpSetting	objSetting;
	private static mpServer		objServer;
	private static mpClient[]	objClient;
	private static File[]		clientFile;
	private static mpGUI		jWindow;
	private static int iClientCount;
	private static boolean bEnd;
	public static boolean bConsole = false;
	public static boolean bDebug;
	public static boolean bFirstUpdate = true;
	
    public static void main(String[] args) throws IOException {
		try {
			String sConsole = args[0];
			if(sConsole.equals("-console")) {
				bConsole = true;
			}
			String sDebug = args[1];
			if(sDebug.equals("-debug")) {
				bDebug = true;
			}
		} catch (ArrayIndexOutOfBoundsException ex) {};
		if(!bConsole) {
			// создаем окно
			//initWindow();
			jWindow = new mpGUI();
			jWindow.setVisible(true);
		}
		// включаем дебаггер
		__initDebugger();
		// создаем объект настроек
		objSetting = new mpSetting();
		// создаем объект сервера
		objServer = new mpServer(objSetting.sServerPath, objSetting.iServerTimeSync);
		// создаем объекты клиентов
		objClient = new mpClient[objSetting.iClientCount];
		iClientCount = objSetting.iClientCount;
		for(int i = 0; i < iClientCount; i++) {
			objClient[i] = new mpClient(i, objSetting.sClientPath[i], objServer);
		}
		if(!bConsole) {
			// иницилизируем содержимое
			jWindow.setComponents();
		}
		// инициализируем отдельный поток для клиентов
		mpMain clientThread = new mpMain();
		// объявим параллельный поток демоном
		//clientThread.setDaemon(true);
		// запуск параллельного потока
        clientThread.start();
		// управление с терминала (консоли)
		if(bConsole) {
			String sInput;
			Scanner sc = new Scanner(System.in);
			do {
				sInput = sc.nextLine();
				switch (sInput) {
					case "quit":
						bEnd = true;
						sc.close();
						break;
					case "debug":
						bDebug = true;
						break;
				}
			} while(!bEnd);
		} else {
			// управление с граф интерфейса
			do {
				try {
					Thread.sleep(2000);
					if(!bConsole) {
						jWindow.getStateDebugCheckBox();
					}
			} catch (InterruptedException ex) {}
			} while(!bEnd);
		}
		// останавливаем параллельный поток
		clientThread.interrupt();
		// выключаем дебаггер
		__destroyDebugger();
    }

	// второй поток для объектов клиентов
	@Override
	public void run() {
		log("");
		log("run client thread.");
		long[] lLastModified = new long[iClientCount];
		clientFile = new File[iClientCount];
		for(int i = 0; i < iClientCount; i++) {
			clientFile[i] = new File(objSetting.sClientPath[i]);
			objClient[i].updateClient();
			lLastModified[i] = clientFile[i].lastModified();
		}
		bFirstUpdate = false;
		
		do {
			try {
				Thread.sleep(objSetting.iServerTimeSync);
				
				for (int i = 0; i < iClientCount; i++) {
					if(clientFile[i].lastModified() != lLastModified[i]) {
						log("");
						objLog(i, objClient[i], "file \"persistent.sfs\" has been updated.");
						log("object: " + objClient[i].toString() + " file: " + clientFile[i].getPath() + " read succesfully..");
						objLog(i, objClient[i], "last modified: " + clientFile[i].lastModified());
						// обновляемся
						objClient[i].updateClient();
						lLastModified[i] = clientFile[i].lastModified();
						if(i + 1 < iClientCount) {
							lLastModified[i + 1] = clientFile[i + 1].lastModified();
						} else if(i - 1 >= 0) {
							lLastModified[i - 1] = clientFile[i - 1].lastModified();
						}
						objLog(i, objClient[i], "update succesfully.");
					}
				}
				
			} catch (InterruptedException ex) {
				return;
			}
		} while (!bEnd);
	}
	
	public static mpServer getServer() {
		return objServer;
	}
	
	public static mpClient getClient(int iID) {
		return objClient[iID];
	}
	
	public static mpGUI getWindow() {
		if (!bConsole) {
			return jWindow;
		} else return null;
	}
	
	public static int getClientCount() {
		return iClientCount;
	}
	
////////////////////////////////////////////////////////////////////////////////	
// дебаггер
////////////////////////////////////////////////////////////////////////////////
	public static void __initDebugger() {
		mpLog.__init();
	}
	public static void __destroyDebugger() {
		mpLog.__destroy();
	}
	public static void log(Object oObj) {
		mpLog.dbgLog(oObj);
	}
	public void srvLog(Object oClassObj,Object oObj) {
		mpLog.srvLog(oClassObj, oObj);
	}
	public void objLog(int iID, Object oClassObj, Object oObj) {
		mpLog.objLog(oClassObj, oObj + " ID:" + objClient[iID].getClientID());
	}
}
